/**
 * 
 */
package id.ac.gunadarma.paracorp.services;

import id.ac.gunadarma.paracorp.common.Constant;
import id.ac.gunadarma.paracorp.model.EnglishSentence;
import id.ac.gunadarma.paracorp.model.TranslatedSentence;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zkoss.util.media.Media;

import edu.berkeley.nlp.mt.Alignment;
import edu.berkeley.nlp.wordAlignment.combine.CombinedAligner;

/**
 * @author rezalesmana
 *
 */
@Service
public class UploadService {
	
	@Autowired
	private EnglishSentenceService englishSentenceService;
	
	@Autowired
	private TranslatedSentenceService translatedSentenceService;

	private String language = Constant.INDONESIA;
	private EnglishSentence englishSentence;
	private String english;
	private TranslatedSentence translatedSentence;
	private String translated;
	private List<TranslatedSentence> uploadResult = new ArrayList<TranslatedSentence>();
	private int index = 1;
	private boolean firstMessage = true;
	private boolean msgidMode = false;
	private boolean msgstrMode = false;
	
	public List<TranslatedSentence> processTranslateFiles(Media[] files, String language) {
		uploadResult = new ArrayList<TranslatedSentence>();
		this.setLanguage(language);
		for(Media media : files) {
			processFile( media );
			reset();
		}

		System.out.println("SIZE : " + uploadResult.size());
		
		return uploadResult;
	}
	
	private void processFile( Media media ) {
		try {
			BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(media.getStreamData()));
			String currentLine;
			
			while((currentLine = bufferedReader.readLine()) != null) {
				processLine(currentLine);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void processLine(String currentLine) {
		System.out.println("Processing line no : " + index);
		index++;
		if((!msgidMode && !msgstrMode) &&
				currentLine.trim().length() >= 5 && currentLine.trim().substring(0, 5).equals("msgid")) {
			msgidMode = true; 
			msgstrMode = false;
			if(language != null) {
				translatedSentence = new TranslatedSentence();
				translatedSentence.setLanguage(this.getLanguage());
			}
		} else if(msgidMode && 
				currentLine.trim().length() >= 6 && currentLine.trim().substring(0, 6).equals("msgstr")) {
			msgidMode = false;
			msgstrMode = true;
		} else if(msgstrMode && currentLine.trim().equals("")) {
			msgidMode = false;
			msgstrMode = false;
			finishProcessingMessageMode();
		}
		
		if(msgidMode) {
			if(currentLine.trim().length() >= 5 && currentLine.trim().substring(0, 5).equals("msgid")) {
				english = currentLine.trim().substring(5, currentLine.length());
			} else {
				english += currentLine.trim();
			}
		} else if(msgstrMode) {
			if(currentLine.trim().length() >= 6 && currentLine.trim().substring(0, 6).equals("msgstr")) {
				translated = currentLine.trim().substring(6, currentLine.length());
			} else {
				translated += currentLine.trim();
			}
		}	
	}
	
	public String[] processString(String string) {
		string = string.replaceAll("[\\p{Punct}&&[^'.,-]]", "").trim();
		
		if(string.contains(".")) {
			return string.split("."); 
		}
		
		String[] stringArray = { string }; 
		
		return stringArray;
	}
	
	private void finishProcessingMessageMode() {
		if(!firstMessage) {
			String[] englishArray = processString(english);
			String[] translatedArray = processString(translated);
			if(englishArray.length == translatedArray.length) {
				for(int i = 0; i < englishArray.length; i++) {
					if(!englishArray[i].trim().equals("")) {
						englishSentence = englishSentenceService.findBySentence(englishArray[i]);
						if(englishSentence == null) {
							englishSentence = new EnglishSentence();
							englishSentence.setSentence(englishArray[i]);
						}
						
						translatedSentence = new TranslatedSentence();
						translatedSentence.setLanguage(getLanguage());
						translatedSentence.setSentence(translatedArray[i]);
						translatedSentence.setEnglishSentence(englishSentence);
						
						uploadResult.add(translatedSentence);
					}
				}
			}
		} else {
			firstMessage = false;
		}
	}
	
	public boolean upload(List<TranslatedSentence> listTranslatedSentence) {
		translatedSentenceService.save(listTranslatedSentence);
		reset();
		uploadResult = new ArrayList<TranslatedSentence>();
		List<String> englishStrings = new ArrayList<String>();
		List<String> translatedStrings = new ArrayList<String>();
		for(TranslatedSentence translated : listTranslatedSentence) {
			englishStrings.add(translated.getEnglishSentence().getSentence());
			translatedStrings.add(translated.getSentence());
		}
		Alignment alignment = new Alignment(englishStrings, translatedStrings);
		
		CombinedAligner aligner;
		File file = new File("C:\\alignment.txt");
		 
		// if file doesnt exists, then create it
		try {
			if (!file.exists()) {
				file.createNewFile();
			}

			FileWriter fw = new FileWriter(file.getAbsoluteFile());
			BufferedWriter bw = new BufferedWriter(fw);
			bw.write(alignment.toString());
			bw.close();
		}catch(Exception e) {
			e.printStackTrace();
			
		}
		

		
//		System.out.println("OUTPUT : " + alignment.toString());
		
		return true;
	}

	private void reset() {
		index = 1;
		englishSentence = null;
		translatedSentence = null;
		english = null;
		translated = null;
		firstMessage = true;
		msgidMode = false;
		msgstrMode = false;
	}

	public String getLanguage() {
		return language;
	}

	public void setLanguage(String language) {
			
		this.language = language;
	}
	
}
